Dispose
Редактировал(а) Alexandr Fokin 2024/06/02 16:03
Реализация метода Dispose
https://learn.microsoft.com/ru-ru/dotnet/standard/garbage-collection/implementing-dispose
Отчистка неуправляемых и управляемых ресурсов | class BaseClassWithFinalizer : IDisposable { // To detect redundant calls private bool _disposedValue; ~BaseClassWithFinalizer() => Dispose(false); // Public implementation of Dispose pattern callable by consumers. public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } // Protected implementation of Dispose pattern. protected virtual void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects) } // TODO: free unmanaged resources (unmanaged objects) and override finalizer // TODO: set large fields to null _disposedValue = true; } } } |
Отчистка управляемых ресурсов (Соответственно не использует финализацию). | public sealed class Foo : IDisposable { private readonly IDisposable _disposable1; private readonly IDisposable _disposable2; public Foo() { _disposable1 = new Bar(); _disposable2 = new Bar(); } public void Dispose() { _disposable1.Dispose(); _disposable2.Dispose(); } } |
Наследование. Отчистка неуправляемых и управляемых ресурсов. | class DerivedClassWithFinalizer : BaseClassWithFinalizer { // To detect redundant calls private bool _disposedValue; ~DerivedClassWithFinalizer() => this.Dispose(false); // Protected implementation of Dispose pattern. protected override void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects). } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. _disposedValue = true; } // Call the base class implementation. base.Dispose(disposing); } } |
Пример использование механизма отчистки для воскрешения (resurrection) объекта. Можно доработать для использования Dispose (не подавляется финализация, не выполняется повторная регистрация). Если объект внутри себя использует другие финализируемые объекты, то внутри блока финализатора их состояние может быть недетерминировано (скорее всего их придется пересоздавать). | class A { private IObjectPool _pool = ...; ~A() { //will not die. keep a reference in resurectedA. _pool.ReturnToPool(this); GC.ReRegisterForFinalize(this); } } |
Dispose struct и упаковка (boxing) | If my struct implements IDisposable will it be boxed when used in a using statement? When does a using-statement box its argument, when it's a struct? |